#include "clientnntp.h"
#include <iostream>

#define CLEAR ("\033[2J")

using namespace std;

void showNewsGroups(ClientNNTP& nntp, unsigned int& newsgroup)
{
	unsigned int i;
	vector< pair<unsigned int, string> > newsgroups;
	if (!nntp.listNewsGroups(newsgroups)) {
		cout << endl << "Ett fel uppstod när nyhetgrupperna hämtades." << endl;
		newsgroup = 0;
		return;
	}

	cout << "Nyhetsgrupper:" << endl;
	for (i = 0; i < newsgroups.size(); ++i) {
		cout << "\t" << newsgroups[i].first
			<< ". " << newsgroups[i].second;
		if (newsgroup == newsgroups[i].first)
			cout << "\t(Vald)";
		cout << endl;
	}
}

void listArticles(ClientNNTP& nntp, unsigned int& newsgroup)
{
	vector< pair<unsigned int, string> > articles;

	if (!nntp.listArticles(articles, newsgroup)) {
		cout << endl << "Ett fel uppstod när artiklarna hämtades." << endl;
		return;
	}
	
	cout << "Artiklar:" << endl;
	for (size_t i = 0; i < articles.size(); ++i) {
		cout << "\t" << articles[i].first
			<< ". " << articles[i].second << endl;
	}
}

void createNewsGroup(ClientNNTP& nntp)
{
	string s;
	cout << CLEAR << "Ange nyhetsgruppens namn:" << endl;
	getline(cin, s);
	if (!nntp.createNewsGroup(s))
		cout << "Ett fel uppstod när nyhetsgruppen skulle skapas." << endl;
}

void createArticle(ClientNNTP& nntp, unsigned int& newsgroup)
{
	string title;
	string author;
	string text;
	string s;
	cout << CLEAR << "Ange atikelns namn:" << endl;
	getline(cin, title);
	cout << CLEAR << "Ange författarnamn:" << endl;
	getline(cin, author);
	cout << CLEAR << "Ange text (avsluta med en punkt på en egen rad):" << endl;
	do {
	       getline(cin, s);
	       if (s == ".")
		       break;
	       text += s;
	       text += '\n';
	} while (1);

	if (!nntp.createArticle(title, author, text, newsgroup))
		cout << "Ett fel uppstod när artikeln skulle skapas." << endl;
}

void showArticle(ClientNNTP& nntp, unsigned int& newsgroup, stringstream& iss)
{
	unsigned int a;
	string s;
	vector<string> article;
	iss >> a;
	if (!nntp.showArticle(article, a, newsgroup) || article.size() != 3) {
		cout << CLEAR << "Ett fel uppstod när artikeln skulle visas." << endl;
	} else {
		cout << CLEAR << "Titel: " << article[0] << endl << "Författare: " <<
			article[1] << endl << "Text:" << endl << article[2] << endl << endl;
	}
	cout << "Skriv f och sedan enter för att fortsätta." << endl;
	getline(cin, s);
}

void deleteNewsGroup(ClientNNTP& nntp, unsigned int& newsgroup, stringstream& iss)
{
	unsigned int s;
	iss >> s;
	if (newsgroup == s)
		newsgroup = 0;
	if (!nntp.deleteNewsGroup(s))
		cout << "Ett fel uppstod när nyhetsgruppen skulle tas bort." << endl;
}

void deleteArticle(ClientNNTP& nntp, unsigned int& newsgroup, stringstream& iss)
{
	if (newsgroup == 0)
		return;
	unsigned int s;
	iss >> s;
	if (!nntp.deleteArticle(s, newsgroup))
		cout << "Ett fel uppstod när artikeln skulle tas bort." << endl;
}

int main(int argc, char** argv)
{
	string s;
	char c;
	unsigned int newsgroup;

	newsgroup = 0;

	if (argc != 3) {
		cout << "Användning: ./client [server adress] [port nummer]" << endl;
		return 1;
	}

	try {
		ClientNNTP nntp;
		stringstream t(argv[2]);
		t >> newsgroup;
		if (!nntp.connect(argv[1], newsgroup)) {
			cout << "Anslutningen kunde ej etableras." << endl;
			return 1;
		}
		newsgroup = 0;

		while (1) {
			cout << CLEAR;
			if (newsgroup != 0)
				listArticles(nntp, newsgroup);
			showNewsGroups(nntp, newsgroup);

			cout << endl << "Val (kommando innom parantes):" << endl <<
				"Skapa nyhetsgrupp (s), Välj nyhetsgrupp (v #), Lista nyhetsgrupper (l)," << endl << "Ta bort nyhetesgrupp (t #), Skapa artikel (k), Visa artikel (e #)," << endl << "Ta bort artikel (d #), Avsluta (a)." << endl;

			getline(cin, s);
			stringstream iss(s);
			iss >> c;
			
			if (c == 'a')
				break;
			switch (c) {
				case 'l':
					// Lista nyhetsgrupper
					continue;
				case 's':
					// Skapa nyhetesgrupp
					createNewsGroup(nntp);
				break;
				case 'v':
					// Välj nyhetesgrupp
					iss >> newsgroup;
				break;
				case 'd':
					// Ta bort artikel
					deleteArticle(nntp, newsgroup, iss);
				break;
				case 't':
					// Ta bort nyhetsgrupp
					deleteNewsGroup(nntp, newsgroup, iss);
				break;
				case 'k':
					// Skapa artikel
					if (newsgroup == 0) {
						cout << "Välj nyhetsgrupp (endast id):" << endl;
						getline(cin, s);
						iss << s;
						iss >> newsgroup;
					}
						
					createArticle(nntp, newsgroup);
				break;
				case 'e':
					// Visa artikel
					showArticle(nntp, newsgroup, iss);
				break;
			}

		}
	} catch (ConnectionClosedException&) {
		cout << endl << "Ett fel som inte gick att ta hand om har uppstått."
		       << endl <<  "Programmet kommer avslutas." << endl;
	}
	
	return 0;
}
